<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box{position: relative;margin: 30px;}
    .box .middleBox{position: relative;width: 350px;height: 350px;}
    .box .middleBox span{position: absolute;background: rgba(200,0,0,0.6);left:0;top:0;display:none}
    .box .largeBox{width: 350px;height: 350px;position: absolute;left: 400px;top:0;overflow: hidden;display: none;}
    .box .largeBox img{position: absolute;left:0;top:0;}
  </style>
</head>
<body>
  <div class="box">
    <div class="middleBox">
      <img src="./imgs/m0.jpg" alt="">
      <span></span>
    </div>
    <ul class="smallBox">
      <li><img src="./imgs/s0.jpg" alt=""></li>
      <li><img src="./imgs/s1.jpg" alt=""></li>
      <li><img src="./imgs/s2.jpg" alt=""></li>
      <li><img src="./imgs/s0.jpg" alt=""></li>
      <li><img src="./imgs/s1.jpg" alt=""></li>
      <li><img src="./imgs/s2.jpg" alt=""></li>
      <li><img src="./imgs/s0.jpg" alt=""></li>
      <li><img src="./imgs/s1.jpg" alt=""></li>
      <li><img src="./imgs/s2.jpg" alt=""></li>
    </ul>
    <div class="largeBox">
      <img src="./imgs/l0.jpg" alt="">
    </div>
  </div>
</body>
<script>

  // 分析：放大镜，等比例移动
  // 1. 获取元素
  // 补全布局：计算遮罩层尺寸
  // 2. 绑定事件
  //   进入
  //     3. 显示
  //   离开
  //     4. 隐藏
  //   移动
  //     5. 计算移动距离，边界限定
  //     6. 设置给遮罩层
  //     7. 根据遮罩层移动的比例，计算大图要移动的距离，设置给大图

  // 设计
  // function Magnifier(){
  //   // 1. 选择元素
  //   // this.mBox = 
  //   // this.mImg = 
  //   // 补全布局：设置遮罩层尺寸
  //   // 2. 绑定事件
  //   this.addEvent();
  // }
  // Magnifier.prototype.addEvent = function(){
  //   // 进入
  //     // 3. 显示
  //     this.show()
  //   // 离开
  //     // 4. 隐藏
  //     this.hide()
  //   // 移动
  //     this.move()
  //     // 5. 计算移动距离，边界限定
  //     // 6. 设置给遮罩层
  //     // 7. 根据遮罩层移动的比例，计算大图要移动的距离，设置给大图
  // }
  // Magnifier.prototype.show = function(){
  //   // 显示
  // }
  // Magnifier.prototype.hide = function(){
  //   // 隐藏
  // }
  // Magnifier.prototype.move = function(){
  //   // 移动
  // }
  // new Magnifier({})


  // 编程
  function Magnifier({mBox, span, lBox, lBimg}){
    // 1. 选择元素
    this.mBox = mBox;
    this.span = span;
    this.lBox = lBox;
    this.lBimg = lBimg;
    
    // 2. 绑定事件
    this.addEvent();
  }
  Magnifier.prototype.addEvent = function(){
    const that = this;
    // 进入
    this.mBox.onmouseover = function(){
      // 3. 显示
      that.show();
      // 补全布局：计算遮罩层的尺寸
      that.init();
    }
    // 离开
    this.mBox.onmouseout = function(){
      // 4. 隐藏
      that.hide()
    }
    // 移动
    this.mBox.onmousemove = function(eve){
      const e = eve || window.event;
      // 移动
      that.move(e);
    }
  }
  Magnifier.prototype.show = function(){
    // 显示
    this.span.style.display = "block";
    this.lBox.style.display = "block";
  }
  Magnifier.prototype.hide = function(){
    // 隐藏
    this.span.style.display = "none";
    this.lBox.style.display = "none";
  }
  Magnifier.prototype.move = function(e){
    // 5. 计算移动距离：鼠标相对于页面的坐标 - 当前盒子距离包含块的距离 - 包含块距离页面的距离
    let l = e.pageX - this.mBox.offsetLeft - this.mBox.offsetParent.offsetLeft - this.span.offsetWidth/2;
    let t = e.pageY - this.mBox.offsetTop - this.mBox.offsetParent.offsetTop - this.span.offsetHeight/2;
    // 边界限定
    if(l < 0) l = 0;
    if(t < 0) t = 0;
    if( l > this.mBw - this.span.offsetWidth ){
      l = this.mBw - this.span.offsetWidth;
    }
    if( t > this.mBh - this.span.offsetHeight ){
      t = this.mBh - this.span.offsetHeight;
    }
    // 6. 设置给遮罩层
    this.span.style.left = l + "px";
    this.span.style.top = t + "px";
    // 7. 计算遮罩层移动的比例，
    const x = l / (this.mBw - this.span.offsetWidth);
    const y = t / (this.mBh - this.span.offsetHeight);
    // 计算大图要移动的距离，设置给大图
    this.lBimg.style.left = -x * ( this.lBimgW - this.lBw ) + "px";
    this.lBimg.style.top = -y * ( this.lBimgH - this.lBh ) + "px";
  }
  Magnifier.prototype.init = function(){
    // 提前将各个尺寸类属性，保存出来，方便后续使用
    this.lBw = this.lBox.offsetWidth;
    this.lBh = this.lBox.offsetHeight;
    this.lBimgW = this.lBimg.offsetWidth;
    this.lBimgH = this.lBimg.offsetHeight;
    this.mBw = this.mBox.offsetWidth;
    this.mBh = this.mBox.offsetHeight;

    // 补全布局：设置遮罩层尺寸
    // 比例：大框的宽/大图的宽
    const x = this.lBw / this.lBimgW;
    const y = this.lBh / this.lBimgH;
    // 遮罩层的宽：中框的宽 * 比例
    this.span.style.width = x * this.mBw + "px";
    this.span.style.height = y * this.mBh + "px";

    console.log(this.lBw, this.lBimgW);
  }

  new Magnifier({
    mBox: $(".middleBox"),
    span: $(".middleBox span"),
    lBox: $(".largeBox"),
    lBimg: $(".largeBox img"),
  })


  function $(select){
    return document.querySelector(select)
  }

</script>
</html>